package city.spring.modules.oldman.controller;

import city.spring.modules.oldman.entity.GooutRegisterEntity;
import city.spring.modules.oldman.service.GooutRegisterService;
import city.spring.modules.oldman.vo.GooutRegisterVO;
import city.spring.utils.MyBatisUtils;
import city.spring.utils.UserUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Controller：外出登记
 *
 * @author 侯坤林
 * @date 2020-06-17 21:45:59
 */
@RestController
@RequestMapping("/goout_register")
public class GooutRegisterController extends ApiController {
    private final GooutRegisterService gooutRegisterService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<GooutRegisterEntity, ?>> entityOrderFields;

    public GooutRegisterController(GooutRegisterService gooutRegisterService) {
        this.gooutRegisterService = gooutRegisterService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(GooutRegisterEntity::getId);
        entityOrderFields.add(GooutRegisterEntity::getOldmanId);
        entityOrderFields.add(GooutRegisterEntity::getUserId);
        entityOrderFields.add(GooutRegisterEntity::getAccompanyType);
        entityOrderFields.add(GooutRegisterEntity::getAccompanyName);
        entityOrderFields.add(GooutRegisterEntity::getAccompanyTelephone);
        entityOrderFields.add(GooutRegisterEntity::getAccompanyIdCard);
        entityOrderFields.add(GooutRegisterEntity::getAccompanyAddress);
        entityOrderFields.add(GooutRegisterEntity::getGooutTime);
        entityOrderFields.add(GooutRegisterEntity::getPlanReturnTime);
        entityOrderFields.add(GooutRegisterEntity::getActualReturnTime);
        entityOrderFields.add(GooutRegisterEntity::getReason);
        entityOrderFields.add(GooutRegisterEntity::getGmtCreate);
        entityOrderFields.add(GooutRegisterEntity::getGmtModified);
    }

    /**
     * 获取全部的 <strong>外出登记</strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault(sort = {"gmtCreate"}) Pageable pageable, GooutRegisterEntity entity) {
        LambdaQueryChainWrapper<GooutRegisterEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

    /**
     * 分页获取 <strong>外出登记</strong> 列表
     *
     * @param pageable 分页参数信息
     */
    @GetMapping
    public Object list(@PageableDefault(sort = {"gmtCreate"}) Pageable pageable, GooutRegisterVO entity, Date[] gooutTime, Date[] actualReturnTime) {
        QueryWrapper<? extends GooutRegisterEntity> queryWrapper = buildQuery(entity);
        if (gooutTime != null && gooutTime.length == 2) {
            queryWrapper.ge("t1.goout_time", gooutTime[0]);
            queryWrapper.le("t1.goout_time", gooutTime[1]);
        }
        if (actualReturnTime != null && actualReturnTime.length == 2) {
            queryWrapper.ge("t1.actual_return_time", actualReturnTime[0]);
            queryWrapper.le("t1.actual_return_time", actualReturnTime[1]);
        }
        return success(gooutRegisterService.listPage(MyBatisUtils.toPage(pageable), queryWrapper));
    }

    /**
     * 获取一个 <strong>外出登记</strong>
     *
     * @param id 主键ID
     */
    @GetMapping("{id}")
    public Object info(@PathVariable String id) {
        QueryWrapper<GooutRegisterVO> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.id", id);
        List<GooutRegisterVO> records = gooutRegisterService.listPage(new Page<>(), wrapper).getRecords();
        if (records.isEmpty()) {
            return success(null);
        }
        return success(records.get(0));
    }

    /**
     * 添加一个 <strong>外出登记</strong>
     *
     * @param entity 修改后的信息
     */
    @PostMapping
    public Object add(@RequestBody GooutRegisterEntity entity) {
        // 从 Security 上下文中获取当前登录用户的信息，其中 getAuthentication().getName() 是得到当前登录用户ID
        // @see city.spring.modules.system.model.UserDetailsDTO.UserDetailsDTO(city.spring.modules.system.entity.UserEntity)
        entity.setUserId(UserUtils.getPrincipal().getName());
        gooutRegisterService.saveGooutRegister(entity);

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.LOCATION, String.valueOf(entity.getId()));
        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    /**
     * 修改一个 <strong>外出登记</strong>
     *
     * @param id     主键ID
     * @param entity 修改后的信息
     */
    @PutMapping("{id}")
    public Object update(@PathVariable String id, @RequestBody GooutRegisterEntity entity) {
        entity.setId(id);
        gooutRegisterService.updateGooutRegister(entity);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 设置一个 <strong>外出登记</strong> 的返回时间
     *
     * @param id 主键ID
     */
    @PutMapping("{id}/comeBack")
    public Object comeBack(@PathVariable String id) {
        gooutRegisterService.lambdaUpdate()
                .eq(GooutRegisterEntity::getId, id)
                .isNull(GooutRegisterEntity::getActualReturnTime)
                .set(GooutRegisterEntity::getActualReturnTime, new Date())
                .update();
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 删除一个 <strong>外出登记</strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        gooutRegisterService.deleteGooutRegister(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong>外出登记</strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        gooutRegisterService.deleteGooutRegister(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<GooutRegisterEntity> buildLambdaQuery(GooutRegisterEntity entity) {
        LambdaQueryChainWrapper<GooutRegisterEntity> lambdaQuery = gooutRegisterService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), GooutRegisterEntity::getId, entity.getId());
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getOldmanId()), GooutRegisterEntity::getOldmanId, entity.getOldmanId());
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getUserId()), GooutRegisterEntity::getUserId, entity.getUserId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getAccompanyType()), GooutRegisterEntity::getAccompanyType, entity
                .getAccompanyType());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getAccompanyName()), GooutRegisterEntity::getAccompanyName, entity
                .getAccompanyName());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getAccompanyTelephone()), GooutRegisterEntity::getAccompanyTelephone, entity
                .getAccompanyTelephone());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getAccompanyIdCard()), GooutRegisterEntity::getAccompanyIdCard, entity
                .getAccompanyIdCard());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getAccompanyAddress()), GooutRegisterEntity::getAccompanyAddress, entity
                .getAccompanyAddress());
        lambdaQuery.eq(entity.getGooutTime() != null, GooutRegisterEntity::getGooutTime, entity.getGooutTime());
        lambdaQuery.eq(entity.getPlanReturnTime() != null, GooutRegisterEntity::getPlanReturnTime, entity.getPlanReturnTime());
        lambdaQuery.eq(entity.getActualReturnTime() != null, GooutRegisterEntity::getActualReturnTime, entity.getActualReturnTime());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getReason()), GooutRegisterEntity::getReason, entity.getReason());
        lambdaQuery.eq(entity.getGmtCreate() != null, GooutRegisterEntity::getGmtCreate, entity.getGmtCreate());
        lambdaQuery.eq(entity.getGmtModified() != null, GooutRegisterEntity::getGmtModified, entity.getGmtModified());
        return lambdaQuery;
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query wrapper
     */
    private QueryWrapper<? extends GooutRegisterEntity> buildQuery(GooutRegisterVO entity) {
        QueryWrapper<? extends GooutRegisterEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(entity.getId()), "t1.id", entity.getId());
        wrapper.eq(StringUtils.isNotBlank(entity.getOldmanId()), "t1.oldman_id", entity.getOldmanId());
        wrapper.eq(StringUtils.isNotBlank(entity.getUserId()), "t1.user_id", entity.getUserId());
        wrapper.like(StringUtils.isNotBlank(entity.getOldmanName()), "t2.oldman_name", entity.getOldmanName());
        wrapper.like(StringUtils.isNotBlank(entity.getAccompanyType()), "t1.accompany_type", entity.getAccompanyType());
        wrapper.like(StringUtils.isNotBlank(entity.getAccompanyName()), "t1.accompany_name", entity.getAccompanyName());
        wrapper.like(StringUtils.isNotBlank(entity.getAccompanyTelephone()), "t1.accompany_telephone", entity.getAccompanyTelephone());
        wrapper.like(StringUtils.isNotBlank(entity.getAccompanyIdCard()), "t1.accompany_id_card", entity.getAccompanyIdCard());
        wrapper.like(StringUtils.isNotBlank(entity.getAccompanyAddress()), "t1.accompany_address", entity.getAccompanyAddress());
        // wrapper.eq(entity.getGooutTime() != null, "t1.goout_time", entity.getGooutTime());
        // wrapper.eq(entity.getPlanReturnTime() != null, "t1.plan_return_time", entity.getPlanReturnTime());
        wrapper.like(StringUtils.isNotBlank(entity.getReason()), "t1.reason", entity.getReason());
        return wrapper;
    }

}
